home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1995 April / Internet Tools.iso / applic / ncsa / Mac / Telnet2.6 / prerelease / d5 / Telnet 2.6.1d5.src.sit.hqx / Telnet 2.6.1d5 src / source / rs / rsmac.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-01-23  |  32.2 KB  |  1,169 lines

  1. /*
  2.  *
  3.  *      Virtual Screen Kernel Macintosh Real Screen Interface
  4.  *                          (rsmac.c)
  5.  *
  6.  *   National Center for Supercomputing Applications
  7.  *      by Gaige B. Paulsen
  8.  *
  9.  *    This file contains the macintosh real screen calls for the NCSA
  10.  *  Virtual Screen Kernel.
  11.  *
  12.  *      RSbell(w)                   - Ring window w's bell
  13.  *      RScursoff(w)                - Turn the cursor off in w
  14.  *      RScurson(w,x,y)             - Turn the cursor on in w at x,y
  15.  *      RSdraw(w,x,y,a,len,ptr)     - Draw @x,y in w string@ptr for length len
  16.  *      RSdelchars(w,x,y,n)         - Delete n chars in w from x,y
  17.  *      RSdellines(w,t,b,n)         - Delete n lines in region t->b in w
  18.  *      RSerase(w,x1,y1,x2,y2)      - Erase from x1,y1 to x2,y2 in w
  19.  *      RSinitall()                 - Initialize the world if necessary
  20.  *      RSinslines(w,t,b,n)         - Insert n lines in region t->b in w
  21.  *      RSinsstring(w,x,y,a,len,ptr)- Insert len chars @x,y in w attrib a
  22.  *      RSsendstring(w,ptr,len)     - Send string @ptr length len from window w
  23.  *        RSbufinfo( w, total,current)- Tells you the total/current lines in buffer
  24.  *        RSmargininfo( w, total, current)    - Tells you total/current columns in VS
  25.  *
  26.  *
  27.  *  Macintosh only Routines:
  28.  *    NI    RSregnconv( *)                - Convert region to rect coords
  29.  *  NI  RSsetwind(w)                - Set the port and vars to window w
  30.  *  NI  RSsetattr(a)                - Set font/text style to a
  31.  *    NI    RSsetConst(w)
  32.  *    ML    RSattach(w,wind)            - Attach the RS (w) to window wind
  33.  *    ML    RSdetach(w)                - Ready window for go-away
  34.  *    ML    RSselect(w,pt,shift)        - Handle selection RS (w) point (pt) and (shift) if held down
  35.  *    ML    RSzoom(window,code,shifted)    - Zoom Box handling
  36.  *    ML    RSsize( window, where)        - Resize handling
  37.  *    IN    RSgetwindow(w)                - Get the WindowPtr for RS (w)
  38.  *    IN    RSfindvwind(wind)            - Find the (RS/VS) # of wind
  39.  *    IN    RSfindscroll( control, n)    - Find which VS the control is in and which control it is
  40.  *      RSupdate(wind)                - Handle updates on WIND, return 0 if not an RS
  41.  *        RSactivate(w)                - Handle activate events 
  42.  *        RSdeactivate(w)                - Handle deactivate events 
  43.  *        RSGetTextSel(w,table)        - Returns handle to text selection of window w, table->tabs
  44.  *        RSnewwindow( wDims, sb, wid, lines
  45.  *            name,wrap,fnum,fsiz,
  46.  *            showit, goaway)            - Returns VS # of newly created text window -
  47.  *                                      wDims (dimension),sb(scrollback),wid(width 80/132),
  48.  *                                    lines (# of lines, 24 <> 66),
  49.  *                                      name(window), wrap(0/1),fnum,fsiz, showit(vis),goaway(0,1)
  50.  *        RSkillwindow( w)            - Destroys, deallocates, kills window (w)
  51.  *        RSclick(window, eventRecord)- Handle clicks in window (returns false if not RS window)
  52.  *        RShide(w)                    - Hide RS (w)
  53.  *        RSshow(w)                    - Show RS (w)
  54.  *        RScprompt(w, FilterProc)    - Prompt for colors...FilterProc is for Modal Dialog
  55.  *        RSsetcolor(w,n,r,g,b)        - Set one of the 4 colors of RS (w) to R,G,B
  56.  *        RSgetcolor(w,n,r,g,b)        - Get one of the 4 colors of RS (w) into R,G,B
  57.  *        RSmouseintext(w,myPoint)    - Returns true if Mouse is in text part of current RS window
  58.  *        RSskip(w,on)                - Activate/deactivate drawing in an RS
  59.  *        
  60.  *        IN - Informational
  61.  *        ML - Mid Level
  62.  *        NI - Necessary Internal
  63.  *           - Suggested calls
  64.  *
  65.  *      Version Date    Notes
  66.  *      ------- ------  ---------------------------------------------------
  67.  *      0.01    861102  Initial coding -GBP
  68.  *      0.25    861106  Added code from screen.c -GBP
  69.  *      0.50    861113  First compiled edition -GBP
  70.  *        2.1        871130    NCSA Telnet 2.1 -GBP
  71.  *        2.2     880715    NCSA Telnet 2.2 -GBP
  72.  *        2.6        7/92    put globals into struct, cursors into array, and cleaned up 
  73.  *                        some of the font typedefs            Scott Bulmahn
  74.  *        2.6b4    12/92    Cleaned up the code, and added double clicking -- Scott Bulmahn
  75.  *
  76.  */
  77.  
  78. #ifdef MPW
  79. #pragma segment RS
  80. #endif
  81.  
  82. #define __ALLNU__
  83. #include <Palettes.h>
  84. #include <ColorPicker.h>        /* BYU LSC */
  85. #include <stdio.h>
  86. #include <string.h>
  87. #include <ctype.h>
  88.  
  89. #include "TelnetHeader.h"
  90. #include "dialog_resrcdefs.h"
  91. #include "DlogUtils.proto.h"
  92. #include "configure.proto.h"    // For colorboxmodalproc and colorboxproc
  93. #include "maclook.proto.h"
  94. #include "network.proto.h"
  95. #include "menuseg.proto.h"
  96. #include "vskeys.h"
  97. #include "vsdata.h"
  98. #include "vsinterf.proto.h"
  99. #include "vsintern.proto.h"
  100. #include "telneterrors.h"
  101. #include "wind.h"
  102. #include "rsdefs.h"
  103. #include "parse.proto.h"        // For SendNAWSinfo proto
  104. #include "wdefpatch.proto.h"    /* 931112, ragge, NADA, KTH */
  105. #include "url.proto.h"
  106. #include "drag.proto.h"
  107. #include "rsinterf.proto.h"
  108.  
  109. #define NFDEF {0,0,0}
  110. #define NBDEF {65535,65535,65535}
  111. #define BFDEF {0,61183,11060}
  112. #define BBDEF {61183,2079,4938}
  113. #define UFDEF {1,0,0}
  114. #define UBDEF {0,0,0}
  115.  
  116.  
  117. extern WindRec *screens;
  118. extern SysEnvRec    theWorld;
  119. extern short    NumberOfColorBoxes;
  120. extern short    BoxColorItems[8];
  121. extern RGBColor    BoxColorData[8];
  122.  
  123. #include "rsmac.proto.h"
  124.  
  125. short MaxRS;
  126.  
  127. RSdata *RSlocal, *RScurrent;
  128. Rect    noConst,
  129.         RScur;                /* cursor rectangle */
  130.  
  131. RgnHandle RSuRgn;            /* update region */
  132.  
  133. short RSw=-1,         /* last window used */
  134.     RSa=0;          /* last attrib used */
  135. short RScolor=1;        /* true if try to use color stuff */
  136.  
  137. short RScolors[]=
  138.     { 33,            /* black */
  139.       30,            /* white */
  140.       205,            /* red */
  141.       341,            /* green */
  142.       409,            /* blue */
  143.       273,            /* cyan */
  144.       137,            /* magenta */
  145.       69            /* yellow */
  146.       };
  147.  
  148.  
  149. void RSinitall
  150.   (
  151.     short max /* max nr windows to allow */
  152.   )
  153.   /* initializes handling of terminal windows. */
  154.   {
  155.     short i;
  156.     extern SysEnvRec theWorld;
  157.  
  158.     MaxRS = max;
  159.     RSlocal = (RSdata *) NewPtrClear(MaxRS * sizeof(RSdata));
  160.     for (i = 0; i < MaxRS; RSlocal[i++].window = 0L)
  161.       {
  162.         RScurrent = RSlocal + i;
  163.         RScurrent->id = 'RSDA';
  164.         RScurrent->color[0] = 0;            /* Foreground */
  165.         RScurrent->color[1] = 1;            /* Background */
  166.         RScurrent->color[2] = 2;            /* Blink Fore */
  167.         RScurrent->color[3] = 3;            /* Blink Back */
  168.         RScurrent->cursor.top = 0;
  169.         RScurrent->cursor.bottom = 0;
  170.         RScurrent->cursor.left = 0;
  171.         RScurrent->cursor.right = 0;
  172.       }
  173.     RSuRgn = NewRgn();
  174.     RScur.left = 0;
  175.     RScur.top = 0;
  176.     RScur.bottom = 0;
  177.     RScur.right = 0;
  178.     RScolor = theWorld.hasColorQD;
  179.   } /* RSinitall */
  180.  
  181.  
  182. void RSsetConst
  183.   (
  184.     short w
  185.   )
  186.   /* sets "noConst" global to a zero-based rectangle equal in size
  187.     to the specified terminal window. */
  188.   {
  189.   noConst.left = 0;
  190.   noConst.top = 0;
  191.   noConst.right = RSlocal[w].width;
  192.   noConst.bottom = RSlocal[w].height;
  193.   } /* RSsetConst */
  194.  
  195. /****************************************************************************/
  196. /*  Given a window record number, do a SetPort() to the window associated with
  197. *   that window record.
  198. */
  199. short RSsetwind
  200.   (
  201.     short w
  202.   )
  203.   {
  204.     if ((w < 0) || (w > MaxRS))
  205.         return(-3);
  206.     if (RSw != w)                                /* if last window used is different */
  207.       {
  208.         if (RSlocal[w].window == 0L)
  209.             return(-4);
  210.         RScurrent = RSlocal + w;
  211.         RSw = w;
  212.         RSa = -1; /* attributes will need setting */
  213.         SetPort(RScurrent->window);
  214.         return(1);
  215.       }
  216.     SetPort(RScurrent->window);
  217.     return(0);
  218.   } /* RSsetwind */
  219.  
  220. void RSbell
  221.   (
  222.     short w
  223.   )
  224.   /* gives an audible signal associated with the specified window. */
  225.   {
  226.     RSsetwind(w);
  227.     if (FrontWindow() != RScurrent->window)
  228.       {
  229.       /* beep and temporarily invert the window contents, so
  230.         the user sees which window is beeping */
  231.         InvertRect(&RScurrent->window->portRect);
  232.         SysBeep(8);
  233.         InvertRect(&RScurrent->window->portRect);
  234.       }
  235.     else
  236.       /* window is frontmost--just beep */
  237.         SysBeep(8);
  238.   } /* RSbell */
  239.  
  240.  
  241. void RScursoff
  242.   (
  243.     short w
  244.   )
  245.   /* hides the text cursor for the specified window. Assumes it
  246.     is currently being shown. */
  247.   {
  248.     if (RSlocal[w].skip || !RSlocal[w].cursorstate)        /* BYU 2.4.11 */
  249.         return;
  250.     RSsetwind(w);
  251.     RScurrent->cursorstate = 0;                            /* BYU 2.4.11 */
  252.     InvertRect(&RScurrent->cursor);
  253.   } /* RScursoff */
  254.  
  255. void RScurson
  256.   (
  257.     short w,
  258.     short x,
  259.     short y
  260.   )
  261.   /* displays the text cursor for the specified window, at the
  262.     specified position. Assumes it isn't currently being shown. */
  263.   {
  264.     if (RSlocal[w].skip || RSlocal[w].cursorstate)        /* BYU 2.4.11 */
  265.         return;
  266.     RSsetwind(w);
  267.  
  268.     RScurrent->cursor.left = x * RScurrent->fwidth;            /* BYU 2.4.11 */
  269.     RScurrent->cursor.top  = y * RScurrent->fheight;        /* BYU 2.4.11 */
  270.  
  271.     switch (gApplicationPrefs->CursorType) {                                            /* BYU 2.4.11 */
  272.         case UNDERSCORECURSOR:                                        /* BYU 2.4.11 */
  273.             RScurrent->cursor.top  += RScurrent->fheight;            /* BYU 2.4.11 */
  274.             RScurrent->cursor.right  = RScurrent->cursor.left + RScurrent->fwidth;    /* BYU 2.4.11 */
  275.             RScurrent->cursor.bottom = RScurrent->cursor.top + 1;    /* BYU 2.4.11 */
  276.             break;
  277.         case VERTICALCURSOR:                                        /* BYU 2.4.11 */
  278.             RScurrent->cursor.left += 2;                            /* BYU 2.4.11 */
  279.             RScurrent->cursor.right  = RScurrent->cursor.left + 1;    /* BYU 2.4.11 */
  280.             RScurrent->cursor.bottom = RScurrent->cursor.top + RScurrent->fheight;    /* BYU 2.4.11 */
  281.             break;
  282.         case BLOCKCURSOR:                                            /* BYU 2.4.11 */
  283.         default:                                                    /* BYU 2.4.11 */
  284.             RScurrent->cursor.right  = RScurrent->cursor.left + RScurrent->fwidth;    /* BYU 2.4.11 */
  285.             RScurrent->cursor.bottom = RScurrent->cursor.top + RScurrent->fheight;    /* BYU 2.4.11 */
  286.             break;
  287.     }
  288.  
  289.     if (!gApplicationPrefs->BlinkCursor) {                                    /* BYU 2.4.11 */
  290.         RScurrent->cursorstate = 1;                        /* BYU 2.4.11 */
  291.         InvertRect(&RScurrent->cursor);                    /* BYU 2.4.11 */
  292.     }                                                    /* BYU 2.4.11 */
  293.   } /* RScurson */
  294.  
  295.  
  296. /* sets the text attributes for drawing into the current window. */
  297. void RSsetattr(short a)
  298. {
  299.        if (VSisgrph(a))
  300.         TextFont(74); /* use "NCSA VT" font for special graphics */
  301.     else
  302.         RSTextFont(RScurrent->fnum,RScurrent->fsiz,a);     /* BYU - use user-selected text font */
  303.  
  304.     TextSize(RScurrent->fsiz);
  305.  
  306. /* BYU - bold system fonts don't work (they overwrite the scroll bars), 
  307.          but NCSA's 9 point Monaco bold works okay. */
  308.  
  309.     TextFace((a & outline) >> 1);     /* BYU - do outline as underline setting */
  310.  
  311.  
  312.   /* set up reverse video setting */
  313.     if (RScolor)
  314.       {
  315.         if (VSisrev(a))
  316.             TextMode(notSrcCopy);
  317.         else
  318.             TextMode(srcCopy);
  319.       }
  320.     else
  321.       {
  322.         if (VSisrev(a))
  323.           {
  324.             BackPat(PATTERN(qd.black));    /* Reverses current attributes regard */
  325.             PenPat(PATTERN(qd.white));    /* less of the color, etc.... */
  326.           }
  327.         else
  328.           {
  329.             BackPat(PATTERN(qd.white));
  330.             PenPat(PATTERN(qd.black));
  331.           } /* if */
  332.       } /* if */
  333.   /* use colors to stand in for blink setting */
  334.     if (VSisblnk(a))
  335.       {
  336.         if (RScolor)
  337.           {
  338.             PmForeColor(2);
  339.             PmBackColor(3);
  340.           }
  341.         else
  342.           {
  343.             ForeColor((long) RScolors[RScurrent->color[2]]);    /* Blink foreground */
  344.             BackColor((long) RScolors[RScurrent->color[3]]);    /* Blink Background */
  345.           } /* if */
  346.       }
  347.     else
  348.       {
  349.         if (RScolor)
  350.           {
  351.             PmForeColor(0);
  352.             PmBackColor(1);
  353.           }
  354.         else
  355.           {
  356.             ForeColor((long) RScolors[RScurrent->color[0]]);    /* normal foreground */
  357.             BackColor((long) RScolors[RScurrent->color[1]]);    /* normal Background */
  358.           } /* if */
  359.       } /* if */
  360.     RSa = a;
  361.   } /* RSsetattr */
  362.  
  363.  
  364. void RSTextFont(short myfnum, short myfsiz, short myface)                 /* BYU */
  365. {                                        /* BYU */
  366.     if ((myfnum == monaco) &&             /* BYU - If Monaco, size 9, and bold, then */
  367.         (myfsiz == 9) &&                /* BYU */
  368.         (myface & bold))    {            /* BYU */
  369.         TextFont(75);                    /* BYU - use NCSA's Monaco. */
  370.     } else {                            /* BYU */
  371.         TextFont(myfnum);                /* BYU */
  372.     }                                    /* BYU */
  373. }                                        /* BYU */
  374.  
  375.  
  376. #ifdef    NO_UNIVERSAL
  377. #define LMGetHiliteMode() (* (unsigned char *) 0x0938)
  378. #define LMSetHiliteMode(HiliteModeValue) ((* (unsigned char *) 0x0938) = (HiliteModeValue))
  379. #endif
  380.  
  381. void DoHiliteMode(void)        /* BYU LSC */
  382.   /* enables use of highlighting in place of simple color inversion
  383.     for next QuickDraw operation. */
  384.   {
  385.       
  386.       LMSetHiliteMode(LMGetHiliteMode() & 0x7F);
  387. //    char *p = (char *) 0x938; /* pointer to HiliteMode low-memory global */
  388. //    *p = *p & 0x7f; /* clear the HiliteBit */
  389.   } /* HiliteMode */
  390.  
  391. void RSinvText
  392.   (
  393.     short w, 
  394.     Point curr,
  395.     Point last,
  396.     RectPtr constrain /* don't highlight anything outside this rectangle */
  397.   )
  398.   /* highlights the text from curr to last inclusive. */
  399.   {
  400.     Rect temp, temp2;
  401.     Point lb, ub;
  402.  
  403.     RSsetwind(w);
  404.   /* normalize coordinates with respect to visible area of virtual screen */
  405.     curr.v -= RScurrent->topline;
  406.     curr.h -= RScurrent->leftmarg;
  407.     last.v -= RScurrent->topline;
  408.     last.h -= RScurrent->leftmarg;
  409.  
  410.     if (curr.v == last.v)
  411.       {
  412.       /* highlighted text all on one line */
  413.         if (curr.h < last.h) /* get bounds the right way round */
  414.           {
  415.             ub = curr;
  416.             lb = last;
  417.           }
  418.         else
  419.           {
  420.             ub = last;
  421.             lb = curr;
  422.           } /* if */
  423.         MYSETRECT /* set up rectangle bounding area to be highlighted */
  424.           (
  425.             temp,
  426.             (ub.h + 1) * RScurrent->fwidth,
  427.             ub.v * RScurrent->fheight,
  428.             (lb.h + 1) * RScurrent->fwidth,
  429.             (lb.v + 1) * RScurrent->fheight
  430.           );
  431.         SectRect(&temp, constrain, &temp2); /* clip to constraint rectangle */
  432.         DoHiliteMode();                        /* BYU LSC */
  433.         InvertRect(&temp2);
  434.       }
  435.     else
  436.       {
  437.       /* highlighting across more than one line */
  438.         if (curr.v < last.v)
  439.             ub = curr;
  440.         else
  441.             ub = last;
  442.         if (curr.v > last.v)
  443.             lb = curr;
  444.         else
  445.             lb = last;
  446.         MYSETRECT /* bounds of first (possibly partial) line to be highlighted */
  447.           (
  448.             temp,
  449.             (ub.h + 1) * RScurrent->fwidth,
  450.             ub.v * RScurrent->fheight,
  451.             RScurrent->width,
  452.             (ub.v + 1) * RScurrent->fheight
  453.           );
  454.         SectRect(&temp, constrain, &temp2); /* clip to constraint rectangle */
  455.         DoHiliteMode();                        /* BYU LSC */
  456.         InvertRect(&temp2);
  457.         MYSETRECT /* bounds of last (possibly partial) line to be highlighted */
  458.           (
  459.             temp,
  460.             0,
  461.             lb.v * RScurrent->fheight,
  462.             (lb.h + 1) * RScurrent->fwidth,
  463.             (lb.v + 1) * RScurrent->fheight
  464.           );
  465.         SectRect(&temp, constrain, &temp2); /* clip to constraint rectangle */
  466.         DoHiliteMode();                        /* BYU LSC */
  467.         InvertRect(&temp2);
  468.  
  469.         if (lb.v - ub.v > 1) /* highlight extends across more than two lines */
  470.           {
  471.           /* highlight complete in-between lines */
  472.             SetRect
  473.               (
  474.                 &temp,
  475.                 0,
  476.                 (ub.v + 1) * RScurrent->fheight,
  477.                 RScurrent->width,
  478.                 lb.v * RScurrent->fheight
  479.               );
  480.             SectRect(&temp, constrain, &temp2); /* clip to constraint rectangle */
  481.             DoHiliteMode();                        /* BYU LSC */
  482.             InvertRect(&temp2);
  483.  
  484.           } /* if */
  485.       } /* if */
  486.   } /* RSinvText */
  487.  
  488. void RSdraw
  489.   (
  490.     short w, /* window number */
  491.     short x, /* starting column */
  492.     short y, /* line on which to draw */
  493.     short a, /* text attributes */
  494.     short len, /* length of text to draw */
  495.     char *ptr /* pointer to text */
  496.   )
  497.   /* draws a piece of text (assumed to fit on a single line) in a window,
  498.     using the specified attributes. If any part of the text falls
  499.     within the current selection, it will be highlighted. */
  500.   {
  501.     Rect rect;
  502.     short ys;
  503.  
  504.     if (RSlocal[w].skip)
  505.         return;
  506.     RSsetwind(w);
  507. //    RSsetattr(0);        JMB 2.6.1d4
  508.  
  509.     ys = y * RScurrent->fheight;
  510.     MYSETRECT /* set up rectangle bounding text being drawn */
  511.       (
  512.         rect,
  513.         x * RScurrent->fwidth,
  514.         ys,
  515.         (x + len) * RScurrent->fwidth,
  516.         ys + RScurrent->fheight
  517.       );
  518.  
  519.     if (RSa != a)
  520.         RSsetattr(a);
  521.  
  522.     if (x <= 0)            /* BYU 2.4.12 - Without this, 1 pixel column of reverse */
  523.       rect.left = -3;    /* BYU 2.4.12 - video text does not clear at left margin */
  524.  
  525.     EraseRect(&rect);
  526.  
  527.     if (x <= 0)            /* BYU 2.4.12 - Okay, just putting it back the way it was */
  528.       rect.left = 0;    /* BYU 2.4.12 */
  529.  
  530.     MoveTo(x * RScurrent->fwidth, ys + RScurrent->fascent);
  531.     
  532.     if (RScurrent->monospaced) {
  533.         DrawText(ptr, 0, len);
  534.         }
  535.     else {
  536.         while (len--) {
  537.             /* draw the characters one at a time to defeat the proportional spacing */
  538.             DrawChar(*ptr++);
  539. //            MoveTo((++x) * RScurrent->fwidth, ys);  /*good version */ JMB 2.6.1d4 
  540.             Move(RScurrent->fwidth, 0);
  541.             x++;
  542.             }
  543.         }
  544.  
  545.     if (RScurrent->selected)
  546.         RSinvText(w, *(Point *) &RScurrent->anchor,
  547.             *(Point *) &RScurrent->last, &rect);
  548.   } /* RSdraw */
  549.  
  550. void RSdelcols
  551.   (
  552.     short w,
  553.     short n /* number of columns to scroll */
  554.   )
  555.   /* scrolls the entire visible display of a virtual screen the
  556.     specified number of columns to the left, blanking out
  557.     the newly-revealed area. */
  558.   {
  559.     Rect rect;
  560.  
  561.     if (RSlocal[w].skip)
  562.         return;
  563.     RSsetwind(w);
  564.     MYSETRECT /* bounds of entire text area, for scrolling */
  565.       (
  566.         rect,
  567.         0,
  568.         0,
  569.         RScurrent->width,
  570.         RScurrent->height
  571.       );
  572.     ScrollRect(&rect, -n * RScurrent->fwidth, 0, RSuRgn);
  573.     InvalRgn(RSuRgn);
  574.     ValidRect(&rect); /* any necessary redrawing in newly-revealed area will be done by caller */
  575.     MYSETRECT /* bounds of newly-revealed area */
  576.       (
  577.         rect,
  578.         RScurrent->width - (n * RScurrent->fwidth),
  579.         0,
  580.         RScurrent->width,
  581.         RScurrent->height
  582.       );
  583.     if (RScurrent->selected)
  584.       /* highlight any newly-revealed part of the current selection */
  585.         RSinvText(w, *(Point *) &RScurrent->anchor,
  586.             *(Point *) &RScurrent->last, &rect);
  587.   } /* RSdelcols */
  588.  
  589. void RSdelchars
  590.   (
  591.     short w, /* affected window */
  592.     short x, /* column to delete from */
  593.     short y, /* line on which to do deletion */
  594.     short n /* number of characters to delete */
  595.   )
  596.   /* deletes the specified number of characters from the specified
  597.     position to the right, moving the remainder of the line to the
  598.     left. */
  599.   {
  600.     Rect rect;
  601.  
  602.     if (RSlocal[w].skip)
  603.         return;
  604.     RSsetwind(w);
  605.     RSsetattr(0); /* avoid funny pen modes */
  606.     MYSETRECT /* bounds of area from starting column to end of line */
  607.       (
  608.         rect,
  609.         x * RScurrent->fwidth,
  610.         y * RScurrent->fheight,
  611.         RScurrent->width,
  612.         (y + 1) * RScurrent->fheight
  613.       );
  614.     if ((x + n) * RScurrent->fwidth > RScurrent->width)
  615.       /* deleting to end of line */
  616.         EraseRect(&rect);
  617.     else
  618.       {
  619.       /* scroll remainder of line to the left */
  620.         ScrollRect(&rect, - RScurrent->fwidth * n, 0, RSuRgn);
  621.         InvalRgn(RSuRgn);
  622.            ValidRect(&rect); /* leave newly-revealed area blank */
  623.         if (RScurrent->selected)
  624.           {
  625.           /* highlight any part of selection which lies in newly-blanked area */
  626.             HLock((Handle) RSuRgn);
  627.             RSinvText(w, *(Point *) &RScurrent->anchor, *(Point *) &RScurrent->last, &((*RSuRgn)->rgnBBox));
  628.             HUnlock((Handle) RSuRgn);
  629.           } /* if */
  630.       } /* if */
  631.   } /* RSdelchars */
  632.  
  633. void RSdellines
  634.   (
  635.     short w, /* affected window */
  636.     short t, /* top line of affected region */
  637.     short b, /* bottom line of affected region */
  638.     short n, /* number of lines to delete */
  639.     short scrolled
  640.       /*
  641.         -ve => cancel current selection, if any;
  642.         +ve => selection has moved up one line;
  643.         0 => don't touch selection
  644.       */
  645.   )
  646.   /* deletes lines at the top of the specified region of a window,
  647.     inserting new blank lines at the bottom, and scrolling up the
  648.     stuff in between. */
  649.   {
  650.     Rect    rect;
  651.     short    RSfheightTimesn, RSfheightTimesbplus1;
  652.  
  653.     if (RSlocal[w].skip)
  654.         return;
  655.  
  656.     RSsetwind(w);
  657.     RSsetConst(w);
  658.     RSsetattr(0); /* avoid funny pen modes */
  659.  
  660.     if (scrolled)
  661.       {
  662.         if (RScurrent->selected && scrolled < 0)
  663.           {
  664.           /* unhighlight and cancel current selection */
  665.             RSinvText(w, *(Point *) &RScurrent->anchor, *(Point *) &RScurrent->last, &noConst);
  666.             RScurrent->selected = 0;
  667.           }
  668.         else
  669.           {
  670.             RScurrent->last.v -= 1;        /* Subtract one from each of the */
  671.             RScurrent->anchor.v -= 1;    /* vertical Selection components */
  672.           } /* if */
  673.       } /* if */
  674.  
  675.     rect.left = -1;                            /* BYU 2.4.12 - necessary */
  676.     rect.right = RScurrent->width;
  677.     rect.top = t * RScurrent->fheight;
  678.     RSfheightTimesbplus1 = (b + 1) * RScurrent->fheight;
  679.     rect.bottom = RSfheightTimesbplus1;
  680.  
  681.   /* adjust the update region to track the scrolled window contents */
  682.       RSfheightTimesn = RScurrent->fheight * n;
  683.     OffsetRgn(((WindowPeek) RScurrent->window)->updateRgn,
  684.         0, -RSfheightTimesn);
  685.     ScrollRect(&rect, 0, -RSfheightTimesn , RSuRgn);
  686.     RSsetattr(VSIw->attrib); /* restore mode for text drawing */
  687.     InvalRgn(RSuRgn);
  688.  
  689.   /* validate the area containing the newly-inserted blank lines. */
  690.   /* any necessary redrawing in newly-revealed area will be done by caller */
  691.     MYSETRECT
  692.       (
  693.         rect,
  694.         0,
  695.         (b - n + 1) * RScurrent->fheight - 1,
  696.         RScurrent->width,
  697.         RSfheightTimesbplus1 + 1
  698.       );
  699.  
  700.     ValidRect(&rect);
  701.   } /* RSdellines */
  702.  
  703. void RSerase
  704.   (
  705.     short w, /* affected window */
  706.     short x1, /* left column */
  707.     short y1, /* top line */
  708.     short x2, /* right column */
  709.     short y2 /* bottom line */
  710.   )
  711.   /* erases a rectangular portion of the screen display, preserving
  712.     the selection highlight. */
  713.   {
  714.     Rect rect;
  715.  
  716.     if (RSlocal[w].skip)
  717.         return;
  718.     RSsetwind(w);
  719.     RSsetattr(0); /* avoid funny pen modes */
  720.     SetRect
  721.       (
  722.         &rect,
  723.         x1 * RScurrent->fwidth,
  724.         y1 * RScurrent->fheight,
  725.         (x2 + 1) * RScurrent->fwidth - 1,
  726.         (y2 + 1) * RScurrent->fheight + 1
  727.       );
  728.     if (rect.left <= 0)                        /* little buffer strip on left */
  729.         rect.left = CHO;
  730.     if (rect.right >= RScurrent->width - 1)
  731.         rect.right = RScurrent->rwidth - 2;    /* clear to edge of window, including edge strip */
  732.     if (rect.bottom >= RScurrent->height - 2)
  733.         rect.bottom = RScurrent->rheight + 1;    /* clear to bottom edge also */
  734.     EraseRect(&rect);
  735.     if (RScurrent->selected)
  736.       /* highlight any part of the selection within the cleared area */
  737.         RSinvText(w, *(Point *) &RScurrent->anchor, *(Point *) &RScurrent->last, &rect);
  738.   } /* RSerase */
  739.  
  740. void RSinslines
  741.   (
  742.     short w, /* affected window */
  743.     short t, /* where to insert blank lines */
  744.     short b, /* bottom of area to scroll */
  745.     short n, /* number of lines to insert */
  746.     short scrolled /* -ve <=> cancel current selection, if any */
  747.   )
  748.   /* inserts blank lines at the top of the given area of the display,
  749.     scrolling the rest of it down. */
  750.   {
  751.     Rect rect;
  752.  
  753.     if (RSlocal[w].skip)
  754.         return;
  755.     RSsetwind(w);
  756.     RSsetConst(w);
  757.     RSsetattr(0); /* avoid funny pen modes */
  758.     if (RScurrent->selected && (scrolled < 0))
  759.       {
  760.       /* unhighlight and cancel selection */
  761.         RSinvText(w, *(Point *) &RScurrent->anchor,
  762.             *(Point *) &RScurrent->last, &noConst);
  763.         RScurrent->selected = 0;
  764.       } /* if */
  765.     rect.left = -1;                        /* BYU 2.4.12 - necessary */
  766.     rect.right = RScurrent->width;
  767.     rect.top = t * RScurrent->fheight;
  768.     rect.bottom = (b + 1) * RScurrent->fheight;
  769.   /* adjust the update region to track the scrolled window contents */
  770.     OffsetRgn(((WindowPeek) RScurrent->window)->updateRgn,
  771.         0, RScurrent->fheight * n);
  772.     ScrollRect(&rect, 0, RScurrent->fheight * n, RSuRgn);
  773.     InvalRgn(RSuRgn);
  774.   /* newly-inserted area is already blank -- validate it to avoid redrawing. */
  775.   /* any necessary redrawing will be done by caller */
  776.     SetRect(&rect, 0, t * RScurrent->fheight - 1,
  777.         RScurrent->width, (t + n) * RScurrent->fheight + 1);
  778.     ValidRect(&rect);
  779.   } /* RSinslines */
  780.  
  781. void RSinscols
  782.   (
  783.     short w,
  784.     short n /* number of columns to insert */
  785.   )
  786.   /* inserts blank columns at the left side of the text display in
  787.     the specified window, scrolling its current contents to the right.
  788.     Maintains the selection highlight, but doesn't move the selection.
  789.     Doesn't even unhighlight text which moves out of the selection area. */
  790.   {
  791.     Rect rect;
  792.  
  793.     if (RSlocal[w].skip)
  794.         return;
  795.     RSsetwind(w);
  796.     SetRect /* bounds of entire text area */
  797.       (
  798.         &rect,
  799.         0,
  800.         0,
  801.         RScurrent->width,
  802.         RScurrent->height
  803.       );
  804.     ScrollRect(&rect, n * RScurrent->fwidth, 0, RSuRgn);
  805.     InvalRgn(RSuRgn);
  806.     ValidRect(&rect); /* any necessary redrawing in newly-revealed area will be done by caller */
  807.     SetRect /* bounds of newly-inserted blank area */
  808.       (
  809.         &rect,
  810.         0,
  811.         0,
  812.         (n + 1) * RScurrent->fwidth - 1,
  813.         RScurrent->height
  814.       );
  815.     if (RScurrent->selected)
  816.       /* highlight any part of the selection in the newly-blanked area */
  817.         RSinvText(w, *(Point *) &RScurrent->anchor, *(Point *) &RScurrent->last, &rect);
  818.   } /* RSinscols */
  819.  
  820. void RSinsstring
  821.   (
  822.     short w, /* affected window */
  823.     short x, /* starting column at which to insert */
  824.     short y, /* line on which to insert */
  825.     short a, /* attributes for inserted text */
  826.     short len, /* length of inserted text */
  827.     char *ptr /* pointer to inserted text */
  828.   )
  829.   /* inserts a string of characters at the specified position, scrolling
  830.     the rest of the line to the right. Highlights any part of the newly-
  831.     inserted text lying within the current selection. */
  832.   {
  833.     Rect rect;
  834.  
  835.     if (RSlocal[w].skip)
  836.         return;
  837.     RSsetwind(w);
  838.     SetRect /* bounds of part of line from specified position to end of line */
  839.       (
  840.         &rect,
  841.         x * RScurrent->fwidth,
  842.         y * RScurrent->fheight,
  843.         RScurrent->width,
  844.         (y + 1) * RScurrent->fheight
  845.       );
  846.     ScrollRect(&rect, len * RScurrent->fwidth, 0, RSuRgn); /* scroll remainder of line to the right */
  847.     if (RSa != a)
  848.         RSsetattr(a);
  849.     InvalRgn(RSuRgn);
  850.     ValidRect(&rect); /* any necessary redrawing in newly-revealed area will be done by caller */
  851.     SetRect /* bounds area to contain inserted string */
  852.       (
  853.         &rect,
  854.         x * RScurrent->fwidth,
  855.         y * RScurrent->fheight,
  856.         (x + len) * RScurrent->fwidth,
  857.         (y + 1) * RScurrent->fheight
  858.       );
  859.     EraseRect(&rect); /* erase area to appropriate background */
  860.     MoveTo
  861.       (
  862.         x * RScurrent->fwidth,
  863.         y * RScurrent->fheight + RScurrent->fascent
  864.       );
  865.     DrawText(ptr, 0, len);
  866.     if (RScurrent->selected)
  867.       /* highlight any part of selection covering the newly-inserted text */
  868.         RSinvText(w, *(Point *) &RScurrent->anchor,
  869.             *(Point *) &RScurrent->last, &rect);
  870.   } /* RSinsstring */
  871.  
  872.  
  873. void RSmargininfo
  874.   (
  875.     short w,
  876.     short total, /* number of invisible character positions (screen width less visible width) */
  877.     short current /* leftmost visible character position */
  878.   )
  879.   /* updates the horizontal scroll bar and associated variables
  880.     to reflect the current view of the virtual screen within the
  881.     specified window. */
  882.   {
  883.     RSlocal[w].leftmarg = current;            /* Adjust local vars */
  884.     if (RSlocal[w].lcurrent != current)
  885.         SetCtlValue(RSlocal[w].left, (RSlocal[w].lcurrent = current));
  886.     if (RSlocal[w].lmax != total)
  887.         SetCtlMax(RSlocal[w].left, (RSlocal[w].lmax = total));
  888.   } /* RSmargininfo */
  889.  
  890.  
  891. void RSbufinfo
  892.   (
  893.     short w, /* affected window */
  894.     short total, /* number of lines of scrollback */
  895.     short current, /* current topmost visible line */
  896.     short bottom /* current bottommost visible line */
  897.   )
  898.   /* readjusts the vertical scroll bar and associated variables
  899.     to reflect the current view of the virtual screen within the
  900.     specified window. */
  901.   {
  902.     RSdata *RSthis;
  903.     short newmax;
  904.  
  905.     RSthis = RSlocal + w;
  906.  
  907.     newmax = (VSgetlines(w) - 1) - (bottom - current);
  908.  
  909.     RSthis->topline = current;            /* Adjust local vars */
  910.     if (RSthis->min != -total)
  911.     {
  912.         //(**RSthis->scroll).contrlMin = (RSthis->min = -total);    // JMB 2.6.1d4
  913.             SetCtlMin(RSthis->scroll, (RSthis->min = -total));
  914.     } /* if */
  915.  
  916.     if (RSthis->current != current)
  917.         SetCtlValue(RSthis->scroll, (RSthis->current = current));
  918.  
  919.     if (RSthis->max != newmax)
  920.     {
  921.         //(**RSthis->scroll).contrlMax = (RSthis->max = newmax);    // JMB 2.6.1d4
  922.         SetCtlMax(RSthis->scroll, (RSthis->max = newmax));
  923.     } /* if */
  924.  
  925.   } /* RSbufinfo */
  926.  
  927.  
  928.  
  929.  
  930. short RSfindscroll                /* Find screen index by control*/
  931.   (
  932.     ControlHandle control,
  933.     short *n
  934.   )
  935.   /* finds the window to which the given scroll bar belongs.
  936.     Returns the window number in *n if found, and a function
  937.     result of 1 for a vertical scroll bar, 2 for a horizontal
  938.     one, or -1 if the window wasn't found. */
  939.   {
  940.   /* look for a vertical scroll bar */
  941.     *n = 0;
  942.     while ((*n < MaxRS) && (control != RSlocal[*n].scroll))
  943.         (*n)++;
  944.     if (*n < MaxRS)
  945.         return (1); /* found it */
  946.   /* look for a horizontal scroll bar */
  947.     *n = 0;
  948.     while ((*n < MaxRS) && (control != RSlocal[*n].left))
  949.         (*n)++;
  950.     if (*n < MaxRS)
  951.         return (2); /* found it */
  952.     return(-1); /* not found */
  953.   } /* RSfindscroll */
  954.  
  955. void RSregnconv
  956.   (
  957.     RgnHandle regn,
  958.     short *x1, /* left (output) */
  959.     short *y1, /* top (output) */
  960.     short *x2, /* right (output) */
  961.     short *y2, /* bottom (output) */
  962.     short fh, /* font character height */
  963.     short fw /* font character width */
  964.   )
  965.   /* converts the bounding box of the specified QuickDraw region
  966.     into units of character positions (using the specified character
  967.     height and width) and returns the results in *x1, *y1, *x2 and *y2. */
  968.   {
  969.     HLock((Handle) regn);
  970.     *y1 = ((*regn)->rgnBBox.top) / fh;
  971.     *y2 = (((*regn)->rgnBBox.bottom) + fh - 1) / fh;
  972.     *x1 = ((*regn)->rgnBBox.left) / fw;
  973.     *x2 = (((*regn)->rgnBBox.right) + fw - 1) / fw;
  974.     HUnlock((Handle) regn);
  975.     if (*x1 < 0)
  976.         *x1 = 0;
  977.     if (*y1 < 0)
  978.         *y1 = 0;
  979.     if (*x2 < 0)
  980.         *x2 = 0;
  981.     if (*y2 < 0)
  982.         *y2 = 0;
  983. #ifdef WHONEEDSIT
  984.     if (*x1> VSIw->maxwidth)
  985.         *x1 = VSIw->maxwidth;
  986.     if (*x2 > VSIw->maxwidth)
  987.         *x2 = VSIw->maxwidth;
  988.     if (*y1 > VSIw->lines)
  989.         *y1 = VSIw->lines;
  990.     if (*y2 > VSIw->lines)
  991.         *y2 = VSIw->lines;
  992. #endif WHONEEDSIT
  993.   } /* RSregnconv */
  994.  
  995.  
  996.  
  997. #define    Fwidthhalf    FWidth/2
  998.  
  999. Point normalize(Point in, short w)
  1000.   /* converts in from a pixel position in local coordinates to
  1001.     a character cell position within the virtual screen corresponding
  1002.     to the specified window. Constrains the position to lie within
  1003.     the currently-visible region of the screen, autoscrolling the
  1004.     screen if necessary. */
  1005.   {
  1006.  
  1007.     if (in.v <0)
  1008.       {
  1009.         in.v = 0;
  1010.         VSscrolback(w, 1);
  1011.       } /* if */
  1012.     if (in.v > RSlocal[w].height)
  1013.       {
  1014.         in.v = RSlocal[w].height;
  1015.         VSscrolforward(w, 1);
  1016.       } /* if */
  1017.     in.v = in.v / FHeight;
  1018.  
  1019.     if (in.h < 0)
  1020.       {
  1021.         in.h = -1;
  1022.         VSscrolleft(w, 1);
  1023.       } /* if */
  1024.     if (in.h > RSlocal[w].width)
  1025.       {
  1026.         in.h = RSlocal[w].width;
  1027.         VSscrolright(w, 1);
  1028.       } /* if */
  1029.   /* in.h = (in.h + Fwidthhalf) / FWidth - 1; */
  1030.   /* the MPW C 3.0 compiler has a bug in its register allocation */
  1031.   /* which keeps the above line from working. So, replace it with this: */
  1032.     in.h = in.h + Fwidthhalf;
  1033.     in.h = in.h / FWidth - 1;
  1034.   /* note the bug has been fixed in the 3.1 compiler. */
  1035.   /* convert to virtual screen coordinates */
  1036.     in.v += RSlocal[w].topline;
  1037.     in.h += RSlocal[w].leftmarg;
  1038.     return(in);
  1039.   } /* normalize */
  1040.  
  1041.     
  1042.  
  1043. void    RSsortAnchors(short w)
  1044. {
  1045.     Point    temp;
  1046.     
  1047.     if (RSlocal[w].anchor.v > RSlocal[w].last.v) {
  1048.         temp = RSlocal[w].anchor;
  1049.         RSlocal[w].anchor = RSlocal[w].last;
  1050.         RSlocal[w].last = temp;
  1051.         }
  1052.         
  1053.     if ((RSlocal[w].anchor.v == RSlocal[w].last.v) && (RSlocal[w].anchor.h > RSlocal[w].last.h)) {
  1054.         temp = RSlocal[w].anchor;
  1055.         RSlocal[w].anchor = RSlocal[w].last;
  1056.         RSlocal[w].last = temp;
  1057.         }
  1058. }    
  1059.  
  1060.  
  1061.  
  1062.  
  1063.  
  1064. void    RSsetsize( short w, short v, short h)
  1065. /*    saves the new size settings for a window, and repositions
  1066.     the scroll bars accordingly. */
  1067. {
  1068.     RSlocal[w].height = ((v - 16 + CVO) / FHeight) * FHeight;
  1069.     RSlocal[w].width = ((h - 16 + CHO) / FWidth) * FWidth;
  1070.     RSlocal[w].rheight = v - 16;
  1071.     RSlocal[w].rwidth = h - 16;
  1072.  
  1073. /*
  1074. *  Get rid of the scroll bars which were in the old size.
  1075. *  Hiding them causes the region to be updated later.
  1076. */
  1077.     if (RSlocal[w].scroll != NULL )
  1078.         HideControl(RSlocal[w].scroll);
  1079.     if (RSlocal[w].left != NULL ) 
  1080.         HideControl(RSlocal[w].left);
  1081.  
  1082.     DrawGrowIcon(RSlocal[w].window);            /* Draw in the necessary bugger */
  1083.  
  1084. /*    move the scroll bars to their new positions and sizes, and redisplay them */    
  1085.  
  1086.     if (RSlocal[w].scroll != NULL ) {
  1087.         SizeControl(RSlocal[w].scroll, 16, (v - 13));
  1088.         MoveControl(RSlocal[w].scroll, (h - 15) + CHO, -1 + CVO);
  1089.         ShowControl(RSlocal[w].scroll);
  1090.         }
  1091.     if (RSlocal[w].left != NULL ) {
  1092.         SizeControl(RSlocal[w].left, (h - 13), 16);
  1093.         MoveControl(RSlocal[w].left, -1 + CHO,  (v - 15) + CVO);
  1094.         ShowControl(RSlocal[w].left);
  1095.         }
  1096.         
  1097.     SetRect(&RSlocal[w].textrect, 0, 0, RSlocal[w].rwidth, RSlocal[w].rheight);
  1098.     
  1099. } /* RSsetsize */
  1100.  
  1101.  
  1102.  
  1103.  
  1104.  
  1105.  
  1106.  
  1107.  
  1108.  
  1109.  
  1110. /**********************************************************************************/
  1111. /*  Make sure at least this much memory is available before allocating more memory
  1112. *   for me.  Returns true or false whether that much is available.
  1113. */
  1114. short RSokmem
  1115.   (
  1116.     short amount
  1117.   )
  1118.   {
  1119.     char *p;
  1120.     
  1121.     if (NULL == (p = NewPtr(amount)))
  1122.         return(0);
  1123.     DisposPtr(p);
  1124.     return(1);
  1125.   } /* RSokmem */
  1126.  
  1127.  
  1128. /*--------------------------------------------------------------------------*/
  1129. /* NCSA: SB - RSbackground                                                    */
  1130. /*    This procedure allows Telnet to switch from dark background to light    */
  1131. /*    background.  Save the current state into the RSdata struct, so that        */
  1132. /*     we know our background state next time we want to do anything.            */
  1133. /*    Make sure the screen contents (and palette) is updated NOW.                */
  1134. /*--------------------------------------------------------------------------*/
  1135. void RSbackground(short w, short value)
  1136. {
  1137.     RGBColor temp;
  1138.     short x;
  1139.     
  1140.     RSsetwind(w);
  1141.     if ((value && !RSlocal[w].flipped) || (!value && RSlocal[w].flipped))
  1142.         {    
  1143.         RSlocal[w].flipped = !RSlocal[w].flipped;
  1144.  
  1145.         temp = RSlocal[w].RGBs[0];
  1146.         RSlocal[w].RGBs[0] = RSlocal[w].RGBs[1];
  1147.         RSlocal[w].RGBs[1] = temp;
  1148.         
  1149.         SetPort(RSlocal[w].window);
  1150.         InvalRect(&RSlocal[w].window->portRect);
  1151.     
  1152.         for (x = 0; x < 4; x++)
  1153.             SetEntryColor(RSlocal[w].pal, x, &RSlocal[w].RGBs[x]);
  1154.         }
  1155. }
  1156.  
  1157. void RScheckmaxwind(Rect *origRect,short origW, 
  1158.             short origH, short *endW, short *endH)
  1159. {
  1160.     *endW = origW;
  1161.     *endH = origH;
  1162.     
  1163.     if (origW > (TelInfo->screenRect.right - origRect->left -15 ))
  1164.         *endW = TelInfo->screenRect.right - origRect->left -15;
  1165.  
  1166.     if (origH > (TelInfo->screenRect.bottom - origRect->top -15 ))
  1167.         *endH = TelInfo->screenRect.bottom - origRect->top -15;
  1168. }        
  1169.